
import os
import re
import openpyxl
import pandas as pd
from typing import List
from pydantic import BaseModel
from loguru import logger

from config import FILE_PATH


class DataItem(BaseModel):
    name: str
    count: int


class GoodsItem(BaseModel):
    name: str  # 名字
    data_str: str  # 材料字符串
    data: List[DataItem]  # 材料
    type: str  # 专业


class GoodsDB:
    """ 商品数据库管理 """
    def __init__(self, execl_file: str):
        self.execl_file = execl_file

        self.goods_list: List[GoodsItem] = self._get_goods_list()

    def _get_goods_list(self) -> List[GoodsItem]:
        goods_list = list()
        sheet = openpyxl.load_workbook(self.execl_file)['Sheet1']

        for cell in sheet['A'][1:]:
            if cell.value and not sheet.row_dimensions[cell.row].hidden:

                desc: str = sheet['B'][cell.row - 1].value
                desc = desc if desc else ''
                goods_type = sheet['C'][cell.row - 1].value
                goods_type = goods_type if goods_type else ''

                goods_item = GoodsItem(
                    name=cell.value,
                    data_str=desc,
                    data=[],
                    type=goods_type
                )

                if desc:
                    for item in desc.split('&'):
                        goods_name, goods_count = item.split('*')
                        goods_item.data.append(DataItem(
                            name=goods_name, count=goods_count
                        ))

                goods_list.append(goods_item)

        return goods_list

    # def _get_goods_list(self) -> List[GoodsItem]:
    #     goods_list = list()
    #     excel_data = pd.read_excel(self.execl_file, sheet_name='Sheet1', header=0)
    #
    #     if self.goods_type != '全部':
    #         excel_data = excel_data[excel_data['专业'] == self.goods_type]
    #
    #     for index in excel_data.index:
    #         goods_info = excel_data.loc[[index]]
    #
    #         data_str: str = goods_info['材料'].values[0]
    #         data_str = data_str if str(data_str) != 'nan' else ''
    #
    #         goods_item = GoodsItem(
    #             name=goods_info['物品'].values[0],
    #             data_str=data_str,
    #             data=[],
    #             type=goods_info['专业'].values[0]
    #         )
    #
    #         if data_str:
    #             for data_info in data_str.split('&'):
    #                 data_name, data_count = data_info.split('*')
    #                 goods_item.data.append(DataItem(
    #                     name=data_name,
    #                     count=data_count
    #                 ))
    #
    #         goods_list.append(goods_item)
    #
    #     return goods_list

    @staticmethod
    def auc_format(title: str, goods_name_list: set):
        goods_name_list = [f'\"{x}\"' for x in goods_name_list]

        return '^'.join([title, '^'.join(goods_name_list)])

    def auc_search_str(self, title: str = '临时搜索') -> str:
        """ AUC 搜索字符串 """
        goods_name_list = set()

        for goods_item in self.goods_list:
            goods_name_list.add(goods_item.name)

            for data_item in goods_item.data:
                goods_name_list.add(data_item.name)

        search_str = self.auc_format(title=title, goods_name_list=goods_name_list)
        with open(os.path.join(FILE_PATH, '搜索语法.txt'), 'w', encoding='utf-8') as f:
            f.write(search_str)

        logger.info(f'搜索语句: {search_str}')
        return search_str

    @staticmethod
    def auc_parse_search_result():
        """ AUC 解析搜索结果 """
        search_result = dict()
        file_name = os.path.join(FILE_PATH, '搜索结果.txt')

        if not os.path.exists(file_name):
            with open(file_name, 'w') as f:
                f.write('')
            logger.warning(f'将搜索结果粘贴至: {file_name}')
            return search_result

        with open(file_name, 'r', encoding='utf-8') as f:
            for line in f:
                rows = line.strip().replace('\"', '').split(',')
                if len(rows) != 5:
                    logger.warning(rows)
                    continue

                if not rows[0].isdigit():
                    logger.warning(rows)
                    continue

                price = rows[0].strip()
                name = re.sub(r'\(\d+\)', '', rows[1]).strip()
                count = rows[4].strip()
                search_result[name] = dict(
                    price=int(price), count=int(count)
                )

        return search_result

    def get_profit(self):
        search_result: dict = self.auc_parse_search_result()
        if not search_result:
            return

        rows = []

        for goods_item in self.goods_list:
            goods_price = 0
            goods_ah_price = search_result[goods_item.name]['price'] if goods_item.name in search_result else 0

            goods_name_list = set()
            goods_name_list.add(goods_item.name)

            for data_item in goods_item.data:
                goods_name_list.add(data_item.name)
                data_total = data_item.count * search_result[data_item.name]['price'] if data_item.name in search_result else 0
                goods_price += data_total
                logger.info(f'{data_item.name} * {data_item.count} = {data_total}')

            profit = int(goods_ah_price * 0.95 - goods_price)  # 扣除5%手续费
            profit_rate = int(profit / goods_price * 100) if goods_price > 0 else 100
            search_str = self.auc_format(title=f'{goods_item.name}_制作', goods_name_list=goods_name_list)

            logger.info(f"{goods_item.name} | 成本: {goods_price} | AH: {goods_ah_price} | "
                        f"利润: {profit}[{profit_rate}%] | 搜索: {search_str}")

            rows.append((
                goods_item.name, goods_price, goods_ah_price, profit, f'{profit_rate}%',
                goods_item.data_str, search_str
            ))

        sorted_rows = sorted(rows, key=lambda x: x[3], reverse=True)  # 按利润排序
        sorted_rows.insert(0, ('商品', '成本', 'AH价', '利润', '利润率', '材料', '搜索'))

        df = pd.DataFrame(sorted_rows)
        df.to_excel(os.path.join(FILE_PATH, '利润表.xlsx'), index=False, header=False)
